﻿using Game;
using TemplatesDatabase;
using Engine;
namespace Mekiasm
{
    public class SubsystemCampfireBlockBehavior : SubsystemBlockBehavior, IDrawable
    {
        public override int[] HandledBlocks => new int[0];

        public int[] DrawOrders => new int[] { 0 };

        public UpdateOrder UpdateOrder => UpdateOrder.SubsystemPlayers;

        private const int CookeTime = 15;

        public int Value;

        public Vector3 Position;

        public double StartTime;

        public double EndTime;

        private Engine.Graphics.PrimitivesRenderer3D primitivesRenderer3D = new Engine.Graphics.PrimitivesRenderer3D();

        private DrawBlockEnvironmentData drawBlockEnvironmentData = new DrawBlockEnvironmentData();

        public override bool OnInteract(TerrainRaycastResult raycastResult, ComponentMiner componentMiner)
        {
            if (ILibrary.SubsystemGameInfo.TotalElapsedGameTime < EndTime)
            {
                ILibrary.SubsystemPickables.AddPickable(Value, 1, Position + new Vector3(0, 1, 0), raycastResult.Ray.Direction, null);
            }
            else
            {
                ILibrary.SubsystemPickables.AddPickable(GetSuccessValue(Value), 1, Position + new Vector3(0, 1, 0), raycastResult.Ray.Direction, null);
            }
            Value = 0;
            return false;
        }
        public override void OnBlockAdded(int value, int oldValue, int x, int y, int z)
        {
            Position = new Vector3(x, y, z);
        }

        public override void OnBlockGenerated(int value, int x, int y, int z, bool isLoaded)
        {
            Position = new Vector3(x, y, z);
        }

        public override void OnBlockRemoved(int value, int newValue, int x, int y, int z)
        {
            if (ILibrary.SubsystemGameInfo.TotalElapsedGameTime < EndTime)
            {
                ILibrary.SubsystemPickables.AddPickable(Value, 1, Position, new Vector3(1, 0, 1), null);
            }
            else
            {
                ILibrary.SubsystemPickables.AddPickable(GetSuccessValue(Value), 1, Position, new Vector3(1, 0, 1), null);
            }
            Value = 0;
        }

        public bool CheckValue(int v)
        {
            int b = Terrain.ExtractContents(v);
            switch (b)
            {
                case RawMeatBlock.Index: return true;
                case RawBirdBlock.Index: return true;
                case RawFishBlock.Index: return true;
                default: return false;
            }
        }

        public float GetHeight()
        {
            int v = ILibrary.SubsystemTerrain.Terrain.GetCellValueFast((int)Position.X, (int)Position.Y, (int)Position.Z);
            int size = Terrain.ExtractData(v);
            if (size > 9)
            {
                return 0.9f;
            }
            else if (size > 4f)
            {
                return 0.7f;
            }
            return 0.6f;
        }

        public int GetSuccessValue(int v)
        {
            int b = Terrain.ExtractContents(v);
            switch (b)
            {
                case RawMeatBlock.Index: return CookedMeatBlock.Index;
                case RawBirdBlock.Index: return CookedBirdBlock.Index;
                case RawFishBlock.Index: return CookedFishBlock.Index;
                default: return v;
            }
        }

        public override void OnHitByProjectile(CellFace cellFace, WorldItem worldItem)
        {
            if (Value == 0)
            {
                if (worldItem is Pickable pick && CheckValue(pick.Value))
                {
                    pick.Count--;
                    if (pick.Count == 0) pick.ToRemove = true;
                    Value = pick.Value;
                }
                else if (worldItem is Projectile projectile && CheckValue(projectile.Value))
                {
                    Value = projectile.Value;
                    projectile.ToRemove = true;
                }
                if (Value != 0)
                {
                    StartTime = ILibrary.SubsystemGameInfo.TotalElapsedGameTime;
                    EndTime = StartTime + CookeTime;
                }
            }
        }
        public override void Save(ValuesDictionary valuesDictionary)
        {
            valuesDictionary.SetValue("Start", StartTime);
            valuesDictionary.SetValue("End", EndTime);
            valuesDictionary.SetValue("Value", Value);
        }
        public override void Load(ValuesDictionary valuesDictionary)
        {
            StartTime = valuesDictionary.GetValue<double>("Start", 0);
            EndTime = valuesDictionary.GetValue<double>("End", 0);
            Value = valuesDictionary.GetValue("Value", 0);
            drawBlockEnvironmentData.DrawBlockMode = DrawBlockMode.World;
            drawBlockEnvironmentData.SubsystemTerrain = ILibrary.SubsystemTerrain;
            drawBlockEnvironmentData.Light = 13;
        }

        public void Draw(Camera camera, int drawOrder)
        {
            if (Value != 0)
            {
                double p = MathUtils.Min((ILibrary.SubsystemGameInfo.TotalElapsedGameTime - StartTime) / CookeTime, 1f);
                int b = Terrain.ExtractContents(p < 1f ? Value : GetSuccessValue(Value));
                Matrix matrix = Matrix.CreateRotationX(MathUtils.DegToRad(90f)) * Matrix.CreateTranslation(Position + new Vector3(0.5f, GetHeight(), 0.5f));
                BlocksManager.Blocks[b].DrawBlock(primitivesRenderer3D, Value, Color.White, 0.4f, ref matrix, drawBlockEnvironmentData);
                primitivesRenderer3D.Flush(camera.ViewProjectionMatrix);
            }
        }
    }
}
